//
//  HBImageViewController.swift
//  HBImageTableView
//
//  Created by 伍宏彬 on 2017/5/9.
//  Copyright © 2017年 whb. All rights reserved.
//

import UIKit

protocol ChildVcProtocol {
    func getChildVc() -> UIViewController
    func getTableView() -> UITableView
}

class HBImageViewController: UIViewController {
    
    fileprivate var headHeight: CGFloat = 0
    fileprivate var headBarHeight: CGFloat = 0
    
    fileprivate lazy var imageVCs: [ChildVcProtocol] = [ChildVcProtocol]()
    
    fileprivate var headView: UIView!
    fileprivate var headBarView: UIView!
    
    fileprivate lazy var scrollerView: UIScrollView = {
        let sView = UIScrollView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height))
        sView.isPagingEnabled = true
        sView.bounces = false
        sView.showsHorizontalScrollIndicator = false
        sView.delegate = self
        return sView
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.automaticallyAdjustsScrollViewInsets = false
//        self.navigationController?.navigationBar.isHidden = true
        
        view.addSubview(scrollerView)

    }
    //MARK: 对外方法
    /// 添加子试图
    ///
    /// - Parameters:
    ///   - ChildVCs: 子控制器
    ///   - headView: 头部试图
    ///   - barView: 工具栏
    func image_add(ChildVCs: [ChildVcProtocol], headView: UIView, barView: UIView) {
        
        imageVCs += ChildVCs
        
        self.headView = headView
        self.headBarView = barView
        
        headHeight = self.headView.hb_H
        headBarHeight = self.headBarView.hb_H
        
        view.addSubview(headView)
        view.addSubview(headBarView)
        
        for (index, baseVc) in imageVCs.enumerated() {
            
            baseVc.getTableView().tag = index
            self.addChildViewController(baseVc.getChildVc())
        }
        
        scrollerView.contentSize = CGSize(width: CGFloat(ChildVCs.count) * UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
        
        let baseVc = imageVCs.first!
        
        baseVc.getTableView().contentInset = UIEdgeInsetsMake(headHeight + headBarHeight, 0, 0, 0)
        
        baseVc.getChildVc().view.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
        
        scrollerView.addSubview(baseVc.getChildVc().view)
        
        baseVc.getTableView().addObserver(self, forKeyPath: "contentOffset", options: [.new], context: nil)
        
    }
    
    /// scrollView 滚动到的页码
    ///
    /// - Parameters:
    ///   - scrollView: scrollView
    ///   - index: 页码
    func image_scrollView(scrollView: UIScrollView, willScrollToPageIndex nextPage: Int, currentPageIndex currentPage: Int) {}
    func image_scrollView(scrollView: UIScrollView, didScrolle contentOffset: CGPoint) {}
    
    //MARK: UIScrollView ContentOffset Observe
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        
        let observeTableView = object as! UITableView
    
        guard observeTableView.tag == scrollerView.page else {
            return
        }
        
        if keyPath == "contentOffset"{
            
            let getPoint: CGPoint = change?[.newKey] as! CGPoint
            
            var offset = getPoint.y
            
            if offset < -(headHeight + headBarHeight) {//下拉
                
                //                print(abs(offset) - (headHeight + headBarHeight))
                let pullY = (abs(offset) - (headHeight + headBarHeight))
                
                headView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: headHeight + pullY)
                headView.subviews.first!.frame = headView.bounds
                
                
            }else{
                
                if offset >= -headBarHeight {
                    offset = headBarHeight
                    
                }
                //                print(headHeight - abs(offset))
                headView.hb_Y = -((headHeight + headBarHeight) - abs(offset))
                headView.hb_H = headHeight
            }
            
            headBarView.hb_Y = headView.frame.maxY
            
        }
    }
    
    deinit {
        
        for baseVc in self.childViewControllers {
            
            let getVc = baseVc as! ChildVcProtocol
            
            getVc.getTableView().removeObserver(self, forKeyPath: "contentOffset")
            
        }
        
    }

}
extension HBImageViewController: UIScrollViewDelegate {

    //MARK: UIScrollViewDelegate
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        image_scrollView(scrollView: scrollerView, didScrolle: scrollerView.contentOffset)
    }
    
    func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        
        let totalPages = self.childViewControllers.count
        var currentPage: Int
        var nextPage: Int
        
        if (velocity.x > 0)
        {
            
            let currentPageOffset = ceil((scrollView.contentSize.width -
                scrollView.contentOffset.x) / scrollView.hb_W)
            currentPage = totalPages - Int(currentPageOffset)
            nextPage = (currentPage >= totalPages - 1) ? totalPages - 1 : currentPage + 1
            //            print("scroll right" + "---" + "\(nextPage)")
        }
        else
        {
            
            let currentPageOffset = floor((scrollView.contentSize.width -
                scrollView.contentOffset.x) / scrollView.hb_W)
            currentPage = totalPages - Int(currentPageOffset)
            nextPage = (currentPage <= 0) ? 0 : currentPage - 1
            //            print("scroll left" + "---" + "\(nextPage)")
        }
        
        image_scrollView(scrollView: scrollView, willScrollToPageIndex: nextPage, currentPageIndex: currentPage)
        
        let baseVc = self.childViewControllers[nextPage] as! ChildVcProtocol
        
        
        if self.headBarView.frame.origin == CGPoint.zero, baseVc.getTableView().contentOffset.y >= -self.headBarHeight{
            return
        }
        
        baseVc.getTableView().setContentOffset(CGPoint(x: 0, y: -headBarView.frame.maxY), animated: false)
        
    }
    
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        
        let index = Int(scrollView.contentOffset.x / UIScreen.main.bounds.size.width)
        
        let baseVc = self.childViewControllers[index] as! ChildVcProtocol
        
        guard baseVc.getChildVc().view.superview == nil else {
            return
        }
        
        baseVc.getTableView().contentInset = UIEdgeInsetsMake(headHeight + headBarHeight, 0, 0, 0)
        
        baseVc.getTableView().setContentOffset(CGPoint(x: 0, y: -headBarView.frame.maxY), animated: false)
        
        baseVc.getChildVc().view.frame = CGRect(x: CGFloat(index) * UIScreen.main.bounds.size.width, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
        
        scrollerView.addSubview(baseVc.getChildVc().view)
        
        baseVc.getTableView().addObserver(self, forKeyPath: "contentOffset", options: [.new], context: nil)
        
    }

}
extension UIScrollView {

    var page: Int {
    
        return Int(self.contentOffset.x / self.frame.size.width)
        
    }

}
extension UIView {
    
    var hb_X: CGFloat {
        
        get{
            return self.frame.origin.x
        }
        set{
            var originRect = self.frame
            originRect.origin.x = newValue
            self.frame = originRect
        }
        
    }
    var hb_Y: CGFloat {
        
        get{
            return self.frame.origin.y
        }
        set{
            var originRect = self.frame
            originRect.origin.y = newValue
            self.frame = originRect
        }
        
    }
    var hb_W: CGFloat {
        
        get{
            return self.frame.size.width
        }
        set{
            var originRect = self.frame
            originRect.size.width = newValue
            self.frame = originRect
        }
        
    }
    var hb_H: CGFloat {
        
        get{
            return self.frame.size.height
        }
        set{
            var originRect = self.frame
            originRect.size.height = newValue
            self.frame = originRect
        }
        
    }
    var hb_centerX: CGFloat {
        
        get{
            return self.center.x
        }
        set{
            var originCenter = self.center
            originCenter.x = newValue
            self.center = originCenter
        }
        
    }
    var hb_centerY: CGFloat {
        
        get{
            return self.center.y
        }
        set{
            var originCenter = self.center
            originCenter.y = newValue
            self.center = originCenter
        }
        
    }
    
    func hb_starBoundsAnimation() {
        
        self.transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
        
        UIView.animate(withDuration: 0.25, animations: {
            self.transform = CGAffineTransform(scaleX: 1.1, y: 1.1)
        }, completion: { (Finished) in
            UIView.animate(withDuration: 0.15, animations: {
                self.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
            })
        })
    }
    
    
}
